xref: /openbsd-src/lib/libssl/ssl_ciph.c (revision 62a742911104f98b9185b2c6b6007d9b1c36396c)
1 /* ssl/ssl_ciph.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <stdio.h>
60 #include "objects.h"
61 #include "ssl_locl.h"
62 
63 #define SSL_ENC_DES_IDX		0
64 #define SSL_ENC_3DES_IDX	1
65 #define SSL_ENC_RC4_IDX		2
66 #define SSL_ENC_RC2_IDX		3
67 #define SSL_ENC_IDEA_IDX	4
68 #define SSL_ENC_eFZA_IDX	5
69 #define SSL_ENC_NULL_IDX	6
70 #define SSL_ENC_NUM_IDX		7
71 
72 static EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
73 	NULL,NULL,NULL,NULL,NULL,NULL,
74 	};
75 
76 #define SSL_MD_MD5_IDX	0
77 #define SSL_MD_SHA1_IDX	1
78 #define SSL_MD_NUM_IDX	2
79 static EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
80 	NULL,NULL,
81 	};
82 
83 typedef struct cipher_sort_st
84 	{
85 	SSL_CIPHER *cipher;
86 	int pref;
87 	} CIPHER_SORT;
88 
89 #define CIPHER_ADD	1
90 #define CIPHER_KILL	2
91 #define CIPHER_DEL	3
92 #define CIPHER_ORD	4
93 
94 typedef struct cipher_choice_st
95 	{
96 	int type;
97 	unsigned long algorithms;
98 	unsigned long mask;
99 	long top;
100 	} CIPHER_CHOICE;
101 
102 typedef struct cipher_order_st
103 	{
104 	SSL_CIPHER *cipher;
105 	int active;
106 	int dead;
107 	struct cipher_order_st *next,*prev;
108 	} CIPHER_ORDER;
109 
110 static SSL_CIPHER cipher_aliases[]={
111 	{0,SSL_TXT_ALL, 0,SSL_ALL,   0,SSL_ALL},	/* must be first */
112 	{0,SSL_TXT_kRSA,0,SSL_kRSA,  0,SSL_MKEY_MASK},
113 	{0,SSL_TXT_kDHr,0,SSL_kDHr,  0,SSL_MKEY_MASK},
114 	{0,SSL_TXT_kDHd,0,SSL_kDHd,  0,SSL_MKEY_MASK},
115 	{0,SSL_TXT_kEDH,0,SSL_kEDH,  0,SSL_MKEY_MASK},
116 	{0,SSL_TXT_kFZA,0,SSL_kFZA,  0,SSL_MKEY_MASK},
117 	{0,SSL_TXT_DH,	0,SSL_DH,    0,SSL_MKEY_MASK},
118 	{0,SSL_TXT_EDH,	0,SSL_EDH,   0,SSL_MKEY_MASK|SSL_AUTH_MASK},
119 
120 	{0,SSL_TXT_aRSA,0,SSL_aRSA,  0,SSL_AUTH_MASK},
121 	{0,SSL_TXT_aDSS,0,SSL_aDSS,  0,SSL_AUTH_MASK},
122 	{0,SSL_TXT_aFZA,0,SSL_aFZA,  0,SSL_AUTH_MASK},
123 	{0,SSL_TXT_aNULL,0,SSL_aNULL,0,SSL_AUTH_MASK},
124 	{0,SSL_TXT_aDH, 0,SSL_aDH,   0,SSL_AUTH_MASK},
125 	{0,SSL_TXT_DSS,	0,SSL_DSS,   0,SSL_AUTH_MASK},
126 
127 	{0,SSL_TXT_DES,	0,SSL_DES,   0,SSL_ENC_MASK},
128 	{0,SSL_TXT_3DES,0,SSL_3DES,  0,SSL_ENC_MASK},
129 	{0,SSL_TXT_RC4,	0,SSL_RC4,   0,SSL_ENC_MASK},
130 	{0,SSL_TXT_RC2,	0,SSL_RC2,   0,SSL_ENC_MASK},
131 	{0,SSL_TXT_IDEA,0,SSL_IDEA,  0,SSL_ENC_MASK},
132 	{0,SSL_TXT_eNULL,0,SSL_eNULL,0,SSL_ENC_MASK},
133 	{0,SSL_TXT_eFZA,0,SSL_eFZA,  0,SSL_ENC_MASK},
134 
135 	{0,SSL_TXT_MD5,	0,SSL_MD5,   0,SSL_MAC_MASK},
136 	{0,SSL_TXT_SHA1,0,SSL_SHA1,  0,SSL_MAC_MASK},
137 	{0,SSL_TXT_SHA,	0,SSL_SHA,   0,SSL_MAC_MASK},
138 
139 	{0,SSL_TXT_NULL,0,SSL_NULL,  0,SSL_ENC_MASK},
140 	{0,SSL_TXT_RSA,	0,SSL_RSA,   0,SSL_AUTH_MASK|SSL_MKEY_MASK},
141 	{0,SSL_TXT_ADH,	0,SSL_ADH,   0,SSL_AUTH_MASK|SSL_MKEY_MASK},
142 	{0,SSL_TXT_FZA,	0,SSL_FZA,   0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK},
143 
144 	{0,SSL_TXT_EXP,	0,SSL_EXP,   0,SSL_EXP_MASK},
145 	{0,SSL_TXT_EXPORT,0,SSL_EXPORT,0,SSL_EXP_MASK},
146 	{0,SSL_TXT_SSLV2,0,SSL_SSLV2,0,SSL_SSL_MASK},
147 	{0,SSL_TXT_SSLV3,0,SSL_SSLV3,0,SSL_SSL_MASK},
148 	{0,SSL_TXT_LOW,  0,SSL_LOW,0,SSL_STRONG_MASK},
149 	{0,SSL_TXT_MEDIUM,0,SSL_MEDIUM,0,SSL_STRONG_MASK},
150 	{0,SSL_TXT_HIGH, 0,SSL_HIGH,0,SSL_STRONG_MASK},
151 	};
152 
153 static int init_ciphers=1;
154 static void load_ciphers();
155 
156 static int cmp_by_name(a,b)
157 SSL_CIPHER **a,**b;
158 	{
159 	return(strcmp((*a)->name,(*b)->name));
160 	}
161 
162 static void load_ciphers()
163 	{
164 	init_ciphers=0;
165 	ssl_cipher_methods[SSL_ENC_DES_IDX]=
166 		EVP_get_cipherbyname(SN_des_cbc);
167 	ssl_cipher_methods[SSL_ENC_3DES_IDX]=
168 		EVP_get_cipherbyname(SN_des_ede3_cbc);
169 	ssl_cipher_methods[SSL_ENC_RC4_IDX]=
170 		EVP_get_cipherbyname(SN_rc4);
171 	ssl_cipher_methods[SSL_ENC_RC2_IDX]=
172 		EVP_get_cipherbyname(SN_rc2_cbc);
173 	ssl_cipher_methods[SSL_ENC_IDEA_IDX]=
174 		EVP_get_cipherbyname(SN_idea_cbc);
175 
176 	ssl_digest_methods[SSL_MD_MD5_IDX]=
177 		EVP_get_digestbyname(SN_md5);
178 	ssl_digest_methods[SSL_MD_SHA1_IDX]=
179 		EVP_get_digestbyname(SN_sha1);
180 	}
181 
182 int ssl_cipher_get_evp(c,enc,md)
183 SSL_CIPHER *c;
184 EVP_CIPHER **enc;
185 EVP_MD **md;
186 	{
187 	int i;
188 
189 	if (c == NULL) return(0);
190 
191 	switch (c->algorithms & SSL_ENC_MASK)
192 		{
193 	case SSL_DES:
194 		i=SSL_ENC_DES_IDX;
195 		break;
196 	case SSL_3DES:
197 		i=SSL_ENC_3DES_IDX;
198 		break;
199 	case SSL_RC4:
200 		i=SSL_ENC_RC4_IDX;
201 		break;
202 	case SSL_RC2:
203 		i=SSL_ENC_RC2_IDX;
204 		break;
205 	case SSL_IDEA:
206 		i=SSL_ENC_IDEA_IDX;
207 		break;
208 	case SSL_eNULL:
209 		i=SSL_ENC_NULL_IDX;
210 		break;
211 		break;
212 	default:
213 		i= -1;
214 		break;
215 		}
216 
217 	if ((i < 0) || (i > SSL_ENC_NUM_IDX))
218 		*enc=NULL;
219 	else
220 		{
221 		if (i == SSL_ENC_NULL_IDX)
222 			*enc=EVP_enc_null();
223 		else
224 			*enc=ssl_cipher_methods[i];
225 		}
226 
227 	switch (c->algorithms & SSL_MAC_MASK)
228 		{
229 	case SSL_MD5:
230 		i=SSL_MD_MD5_IDX;
231 		break;
232 	case SSL_SHA1:
233 		i=SSL_MD_SHA1_IDX;
234 		break;
235 	default:
236 		i= -1;
237 		break;
238 		}
239 	if ((i < 0) || (i > SSL_MD_NUM_IDX))
240 		*md=NULL;
241 	else
242 		*md=ssl_digest_methods[i];
243 
244 	if ((*enc != NULL) && (*md != NULL))
245 		return(1);
246 	else
247 		return(0);
248 	}
249 
250 #define ITEM_SEP(a) \
251 	(((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
252 
253 static void ll_append_tail(head,curr,tail)
254 CIPHER_ORDER **head,*curr,**tail;
255 	{
256 	if (curr == *tail) return;
257 	if (curr == *head)
258 		*head=curr->next;
259 	if (curr->prev != NULL)
260 		curr->prev->next=curr->next;
261 	if (curr->next != NULL) /* should always be true */
262 		curr->next->prev=curr->prev;
263 	(*tail)->next=curr;
264 	curr->prev= *tail;
265 	curr->next=NULL;
266 	*tail=curr;
267 	}
268 
269 STACK *ssl_create_cipher_list(ssl_method,cipher_list,cipher_list_by_id,str)
270 SSL_METHOD *ssl_method;
271 STACK **cipher_list,**cipher_list_by_id;
272 char *str;
273 	{
274 	SSL_CIPHER *c;
275 	char *l;
276 	STACK *ret=NULL,*ok=NULL;
277 #define CL_BUF	40
278 	char buf[CL_BUF];
279 	char *tmp_str=NULL;
280 	unsigned long mask,algorithms,ma;
281 	char *start;
282 	int i,j,k,num=0,ch,multi;
283 	unsigned long al;
284 	STACK *ca_list=NULL;
285 	int current_x,num_x;
286 	CIPHER_CHOICE *ops=NULL;
287 	CIPHER_ORDER *list=NULL,*head=NULL,*tail=NULL,*curr,*tail2,*curr2;
288 	int list_num;
289 	int type;
290 	SSL_CIPHER c_tmp,*cp;
291 
292 	if (str == NULL) return(NULL);
293 
294 	if (strncmp(str,"DEFAULT",7) == 0)
295 		{
296 		i=strlen(str)+2+strlen(SSL_DEFAULT_CIPHER_LIST);
297 		if ((tmp_str=Malloc(i)) == NULL)
298 			{
299 			SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
300 			goto err;
301 			}
302 		strcpy(tmp_str,SSL_DEFAULT_CIPHER_LIST);
303 		strcat(tmp_str,":");
304 		strcat(tmp_str,&(str[7]));
305 		str=tmp_str;
306 		}
307 	if (init_ciphers) load_ciphers();
308 
309 	num=ssl_method->num_ciphers();
310 
311 	if ((ret=(STACK *)sk_new(NULL)) == NULL) goto err;
312 	if ((ca_list=(STACK *)sk_new(cmp_by_name)) == NULL) goto err;
313 
314 	mask =SSL_kFZA;
315 #ifdef NO_RSA
316 	mask|=SSL_aRSA|SSL_kRSA;
317 #endif
318 #ifdef NO_DSA
319 	mask|=SSL_aDSS;
320 #endif
321 #ifdef NO_DH
322 	mask|=SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH;
323 #endif
324 
325 #ifndef SSL_ALLOW_ENULL
326 	mask|=SSL_eNULL;
327 #endif
328 
329 	mask|=(ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL)?SSL_DES :0;
330 	mask|=(ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL)?SSL_3DES:0;
331 	mask|=(ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL)?SSL_RC4 :0;
332 	mask|=(ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL)?SSL_RC2 :0;
333 	mask|=(ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL)?SSL_IDEA:0;
334 	mask|=(ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL)?SSL_eFZA:0;
335 
336 	mask|=(ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL)?SSL_MD5 :0;
337 	mask|=(ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL)?SSL_SHA1:0;
338 
339 	if ((list=(CIPHER_ORDER *)Malloc(sizeof(CIPHER_ORDER)*num)) == NULL)
340 		goto err;
341 
342 	/* Get the initial list of ciphers */
343 	list_num=0;
344 	for (i=0; i<num; i++)
345 		{
346 		c=ssl_method->get_cipher((unsigned int)i);
347 		/* drop those that use any of that is not available */
348 		if ((c != NULL) && c->valid && !(c->algorithms & mask))
349 			{
350 			list[list_num].cipher=c;
351 			list[list_num].next=NULL;
352 			list[list_num].prev=NULL;
353 			list[list_num].active=0;
354 			list_num++;
355 			if (!sk_push(ca_list,(char *)c)) goto err;
356 			}
357 		}
358 
359 	for (i=1; i<list_num-1; i++)
360 		{
361 		list[i].prev= &(list[i-1]);
362 		list[i].next= &(list[i+1]);
363 		}
364 	if (list_num > 0)
365 		{
366 		head= &(list[0]);
367 		head->prev=NULL;
368 		head->next= &(list[1]);
369 		tail= &(list[list_num-1]);
370 		tail->prev= &(list[list_num-2]);
371 		tail->next=NULL;
372 		}
373 
374 	/* special case */
375 	cipher_aliases[0].algorithms= ~mask;
376 
377 	/* get the aliases */
378 	k=sizeof(cipher_aliases)/sizeof(SSL_CIPHER);
379 	for (j=0; j<k; j++)
380 		{
381 		al=cipher_aliases[j].algorithms;
382 		/* Drop those that are not relevent */
383 		if ((al & mask) == al) continue;
384 		if (!sk_push(ca_list,(char *)&(cipher_aliases[j]))) goto err;
385 		}
386 
387 	/* ca_list now holds a 'stack' of SSL_CIPHERS, some real, some
388 	 * 'aliases' */
389 
390 	/* how many parameters are there? */
391 	num=1;
392 	for (l=str; *l; l++)
393 		if (ITEM_SEP(*l))
394 			num++;
395 	ops=(CIPHER_CHOICE *)Malloc(sizeof(CIPHER_CHOICE)*num);
396 	if (ops == NULL) goto err;
397 	memset(ops,0,sizeof(CIPHER_CHOICE)*num);
398 
399 	/* we now parse the input string and create our operations */
400 	l=str;
401 	i=0;
402 	current_x=0;
403 
404 	for (;;)
405 		{
406 		ch= *l;
407 
408 		if (ch == '\0') break;
409 
410 		if (ch == '-')
411 			{ j=CIPHER_DEL; l++; }
412 		else if (ch == '+')
413 			{ j=CIPHER_ORD; l++; }
414 		else if (ch == '!')
415 			{ j=CIPHER_KILL; l++; }
416 		else
417 			{ j=CIPHER_ADD; }
418 
419 		if (ITEM_SEP(ch))
420 			{
421 			l++;
422 			continue;
423 			}
424 		ops[current_x].type=j;
425 		ops[current_x].algorithms=0;
426 		ops[current_x].mask=0;
427 
428 		start=l;
429 		for (;;)
430 			{
431 			ch= *l;
432 			i=0;
433 			while (	((ch >= 'A') && (ch <= 'Z')) ||
434 				((ch >= '0') && (ch <= '9')) ||
435 				((ch >= 'a') && (ch <= 'z')) ||
436 				 (ch == '-'))
437 				 {
438 				 buf[i]=ch;
439 				 ch= *(++l);
440 				 i++;
441 				 if (i >= (CL_BUF-2)) break;
442 				 }
443 			buf[i]='\0';
444 
445 			/* check for multi-part specification */
446 			if (ch == '+')
447 				{
448 				multi=1;
449 				l++;
450 				}
451 			else
452 				multi=0;
453 
454 			c_tmp.name=buf;
455 			j=sk_find(ca_list,(char *)&c_tmp);
456 			if (j < 0)
457 				goto end_loop;
458 
459 			cp=(SSL_CIPHER *)sk_value(ca_list,j);
460 			ops[current_x].algorithms|=cp->algorithms;
461 			/* We add the SSL_SSL_MASK so we can match the
462 			 * SSLv2 and SSLv3 versions of RC4-MD5 */
463 			ops[current_x].mask|=cp->mask;
464 			if (!multi) break;
465 			}
466 		current_x++;
467 		if (ch == '\0') break;
468 end_loop:
469 		/* Make sure we scan until the next valid start point */
470 		while ((*l != '\0') && ITEM_SEP(*l))
471 			l++;
472 		}
473 
474 	num_x=current_x;
475 	current_x=0;
476 
477 	/* We will now process the list of ciphers, once for each category, to
478 	 * decide what we should do with it. */
479 	for (j=0; j<num_x; j++)
480 		{
481 		algorithms=ops[j].algorithms;
482 		type=ops[j].type;
483 		mask=ops[j].mask;
484 
485 		curr=head;
486 		curr2=head;
487 		tail2=tail;
488 		for (;;)
489 			{
490 			if ((curr == NULL) || (curr == tail2)) break;
491 			curr=curr2;
492 			curr2=curr->next;
493 
494 			cp=curr->cipher;
495 			ma=mask & cp->algorithms;
496 			if ((ma == 0) || ((ma & algorithms) != ma))
497 				{
498 				/* does not apply */
499 				continue;
500 				}
501 
502 			/* add the cipher if it has not been added yet. */
503 			if (type == CIPHER_ADD)
504 				{
505 				if (!curr->active)
506 					{
507 					ll_append_tail(&head,curr,&tail);
508 					curr->active=1;
509 					}
510 				}
511 			/* Move the added cipher to this location */
512 			else if (type == CIPHER_ORD)
513 				{
514 				if (curr->active)
515 					{
516 					ll_append_tail(&head,curr,&tail);
517 					}
518 				}
519 			else if	(type == CIPHER_DEL)
520 				curr->active=0;
521 			if (type == CIPHER_KILL)
522 				{
523 				if (head == curr)
524 					head=curr->next;
525 				else
526 					curr->prev->next=curr->next;
527 				if (tail == curr)
528 					tail=curr->prev;
529 				curr->active=0;
530 				if (curr->next != NULL)
531 					curr->next->prev=curr->prev;
532 				if (curr->prev != NULL)
533 					curr->prev->next=curr->next;
534 				curr->next=NULL;
535 				curr->prev=NULL;
536 				}
537 			}
538 		}
539 
540 	for (curr=head; curr != NULL; curr=curr->next)
541 		{
542 		if (curr->active)
543 			{
544 			sk_push(ret,(char *)curr->cipher);
545 #ifdef CIPHER_DEBUG
546 			printf("<%s>\n",curr->cipher->name);
547 #endif
548 			}
549 		}
550 
551 	if (cipher_list != NULL)
552 		{
553 		if (*cipher_list != NULL)
554 			sk_free(*cipher_list);
555 		*cipher_list=ret;
556 		}
557 
558 	if (cipher_list_by_id != NULL)
559 		{
560 		if (*cipher_list_by_id != NULL)
561 			sk_free(*cipher_list_by_id);
562 		*cipher_list_by_id=sk_dup(ret);
563 		}
564 
565 	if (	(cipher_list_by_id == NULL) ||
566 		(*cipher_list_by_id == NULL) ||
567 		(cipher_list == NULL) ||
568 		(*cipher_list == NULL))
569 		goto err;
570 	sk_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
571 
572 	ok=ret;
573 	ret=NULL;
574 err:
575 	if (tmp_str) Free(tmp_str);
576 	if (ops != NULL) Free(ops);
577 	if (ret != NULL) sk_free(ret);
578 	if (ca_list != NULL) sk_free(ca_list);
579 	if (list != NULL) Free(list);
580 	return(ok);
581 	}
582 
583 char *SSL_CIPHER_description(cipher,buf,len)
584 SSL_CIPHER *cipher;
585 char *buf;
586 int len;
587 	{
588 	int export;
589 	char *ver,*exp;
590 	char *kx,*au,*enc,*mac;
591 	unsigned long alg,alg2;
592 	static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
593 
594 	alg=cipher->algorithms;
595 	alg2=cipher->algorithm2;
596 
597 	export=(alg&SSL_EXP)?1:0;
598 	exp=(export)?" export":"";
599 
600 	if (alg & SSL_SSLV2)
601 		ver="SSLv2";
602 	else if (alg & SSL_SSLV3)
603 		ver="SSLv3";
604 	else
605 		ver="unknown";
606 
607 	switch (alg&SSL_MKEY_MASK)
608 		{
609 	case SSL_kRSA:
610 		kx=(export)?"RSA(512)":"RSA";
611 		break;
612 	case SSL_kDHr:
613 		kx="DH/RSA";
614 		break;
615 	case SSL_kDHd:
616 		kx="DH/DSS";
617 		break;
618 	case SSL_kFZA:
619 		kx="Fortezza";
620 		break;
621 	case SSL_kEDH:
622 		kx=(export)?"DH(512)":"DH";
623 		break;
624 	default:
625 		kx="unknown";
626 		}
627 
628 	switch (alg&SSL_AUTH_MASK)
629 		{
630 	case SSL_aRSA:
631 		au="RSA";
632 		break;
633 	case SSL_aDSS:
634 		au="DSS";
635 		break;
636 	case SSL_aDH:
637 		au="DH";
638 		break;
639 	case SSL_aFZA:
640 	case SSL_aNULL:
641 		au="None";
642 		break;
643 	default:
644 		au="unknown";
645 		break;
646 		}
647 
648 	switch (alg&SSL_ENC_MASK)
649 		{
650 	case SSL_DES:
651 		enc=export?"DES(40)":"DES(56)";
652 		break;
653 	case SSL_3DES:
654 		enc="3DES(168)";
655 		break;
656 	case SSL_RC4:
657 		enc=export?"RC4(40)":((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)");
658 		break;
659 	case SSL_RC2:
660 		enc=export?"RC2(40)":"RC2(128)";
661 		break;
662 	case SSL_IDEA:
663 		enc="IDEA(128)";
664 		break;
665 	case SSL_eFZA:
666 		enc="Fortezza";
667 		break;
668 	case SSL_eNULL:
669 		enc="None";
670 		break;
671 	default:
672 		enc="unknown";
673 		break;
674 		}
675 
676 	switch (alg&SSL_MAC_MASK)
677 		{
678 	case SSL_MD5:
679 		mac="MD5";
680 		break;
681 	case SSL_SHA1:
682 		mac="SHA1";
683 		break;
684 	default:
685 		mac="unknown";
686 		break;
687 		}
688 
689 	if (buf == NULL)
690 		{
691 		buf=Malloc(128);
692 		if (buf == NULL) return("Malloc Error");
693 		}
694 	else if (len < 128)
695 		return("Buffer too small");
696 
697 	sprintf(buf,format,cipher->name,ver,kx,au,enc,mac,exp);
698 	return(buf);
699 	}
700 
701 char *SSL_CIPHER_get_version(c)
702 SSL_CIPHER *c;
703 	{
704 	int i;
705 
706 	if (c == NULL) return("(NONE)");
707 	i=(int)(c->id>>24L);
708 	if (i == 3)
709 		return("TLSv1/SSLv3");
710 	else if (i == 2)
711 		return("SSLv2");
712 	else
713 		return("unknown");
714 	}
715 
716 /* return the actual cipher being used */
717 char *SSL_CIPHER_get_name(c)
718 SSL_CIPHER *c;
719 	{
720 	if (c != NULL)
721 		return(c->name);
722 	return("(NONE)");
723 	}
724 
725 /* number of bits for symetric cipher */
726 int SSL_CIPHER_get_bits(c,alg_bits)
727 SSL_CIPHER *c;
728 int *alg_bits;
729 	{
730 	int ret=0,a=0;
731 	EVP_CIPHER *enc;
732 	EVP_MD *md;
733 
734 	if (c != NULL)
735 		{
736 		if (!ssl_cipher_get_evp(c,&enc,&md))
737 			return(0);
738 
739 		a=EVP_CIPHER_key_length(enc)*8;
740 
741 		if (c->algorithms & SSL_EXP)
742 			{
743 			ret=40;
744 			}
745 		else
746 			{
747 			if (c->algorithm2 & SSL2_CF_8_BYTE_ENC)
748 				ret=64;
749 			else
750 				ret=a;
751 			}
752 		}
753 
754 	if (alg_bits != NULL) *alg_bits=a;
755 
756 	return(ret);
757 	}
758 
759