Add include dir
[openssl.git] / ssl / ssl_ciph.c
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_TLSV1,0,SSL_SSLV3,0,SSL_SSL_MASK},
149         {0,SSL_TXT_LOW,  0,SSL_LOW,0,SSL_STRONG_MASK},
150         {0,SSL_TXT_MEDIUM,0,SSL_MEDIUM,0,SSL_STRONG_MASK},
151         {0,SSL_TXT_HIGH, 0,SSL_HIGH,0,SSL_STRONG_MASK},
152         };
153
154 static int init_ciphers=1;
155 static void load_ciphers();
156
157 static int cmp_by_name(a,b)
158 SSL_CIPHER **a,**b;
159         {
160         return(strcmp((*a)->name,(*b)->name));
161         }
162
163 static void load_ciphers()
164         {
165         init_ciphers=0;
166         ssl_cipher_methods[SSL_ENC_DES_IDX]= 
167                 EVP_get_cipherbyname(SN_des_cbc);
168         ssl_cipher_methods[SSL_ENC_3DES_IDX]=
169                 EVP_get_cipherbyname(SN_des_ede3_cbc);
170         ssl_cipher_methods[SSL_ENC_RC4_IDX]=
171                 EVP_get_cipherbyname(SN_rc4);
172         ssl_cipher_methods[SSL_ENC_RC2_IDX]= 
173                 EVP_get_cipherbyname(SN_rc2_cbc);
174         ssl_cipher_methods[SSL_ENC_IDEA_IDX]= 
175                 EVP_get_cipherbyname(SN_idea_cbc);
176
177         ssl_digest_methods[SSL_MD_MD5_IDX]=
178                 EVP_get_digestbyname(SN_md5);
179         ssl_digest_methods[SSL_MD_SHA1_IDX]=
180                 EVP_get_digestbyname(SN_sha1);
181         }
182
183 int ssl_cipher_get_evp(c,enc,md)
184 SSL_CIPHER *c;
185 EVP_CIPHER **enc;
186 EVP_MD **md;
187         {
188         int i;
189
190         if (c == NULL) return(0);
191
192         switch (c->algorithms & SSL_ENC_MASK)
193                 {
194         case SSL_DES:
195                 i=SSL_ENC_DES_IDX;
196                 break;
197         case SSL_3DES:
198                 i=SSL_ENC_3DES_IDX;
199                 break;
200         case SSL_RC4:
201                 i=SSL_ENC_RC4_IDX;
202                 break;
203         case SSL_RC2:
204                 i=SSL_ENC_RC2_IDX;
205                 break;
206         case SSL_IDEA:
207                 i=SSL_ENC_IDEA_IDX;
208                 break;
209         case SSL_eNULL:
210                 i=SSL_ENC_NULL_IDX;
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